//
//  BoxStickerView.m
//  StickerDemo
//
//  Created by jingliang on 2017/5/3.
//  Copyright © 2017年 井良. All rights reserved.
//

#import "BoxStickerView.h"


#import "BoxStickerRecognizer.h"

@interface BoxStickerView () <UIGestureRecognizerDelegate>
@property (strong, nonatomic) UIImageView *contentView;
@property (strong, nonatomic) UIImage *contentImage;
@property (strong, nonatomic) UIImageView *deleteControl;
@property (strong, nonatomic) UIImageView *resizeControl;
@property (strong, nonatomic) UIImageView *rightTopControl;
@property (strong, nonatomic) UIImageView *leftBottomControl;
@property (strong, nonatomic) CAShapeLayer *shapeLayer;
@property (assign, nonatomic) CGFloat realScaleProduct;
//@property (assign, nonatomic) CGFloat hypotheticalScaleProduct;

@end

@implementation BoxStickerView

#pragma mark - Initial

- (instancetype)initWithFrame:(CGRect)frame contentImage:(UIImage *)contentImage {
    // 在原来的基础上,对frame进行了一层放大,包裹了四个控制控件,避免处理超出父控件以后的点击事件处理问题
    self = [super initWithFrame:CGRectMake(frame.origin.x - BoxControlItemHalfWidth, frame.origin.y - BoxControlItemHalfWidth, frame.size.width + BoxControlItemWidth, frame.size.height + BoxControlItemWidth)];
    
    if (self) {
        // 创建背景图片 UIImageView,设置frame,添加
        self.contentView = [[UIImageView alloc] initWithFrame:CGRectMake(BoxControlItemHalfWidth, BoxControlItemHalfWidth, frame.size.width, frame.size.height)];
        self.contentImage = contentImage;
        [self addSubview:self.contentView];
        
        // 箭头控制按钮,支持放大 缩小 旋转
        self.resizeControl = [self createResizeControl];
        [self addSubview:self.resizeControl];
        // 删除按钮,支持将当前的贴纸删除
        self.deleteControl = [self createDeleteControl];
        [self addSubview:self.deleteControl];
        // 图片左右翻转的控制按钮
        self.rightTopControl = [self createRightTopControl];
        [self addSubview:self.rightTopControl];
        
        // 左下角的复位按钮,主要作用是,点击以后,位置回到中心点
        self.leftBottomControl = [self createLeftBottomControl];
        [self addSubview:self.leftBottomControl];
        
        // 创建sharpLayer
        [self initShapeLayer];
        [self setupConfig];
        [self attachGestures];
        
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame contentLabelFrame:(CGRect)contentLabelFrame contentImage:(UIImage *)contentImage{

    // 在原来的基础上,对frame进行了一层放大,包裹了四个控制控件,避免处理超出父控件以后的点击事件处理问题
    self = [super initWithFrame:CGRectMake(frame.origin.x - BoxControlItemHalfWidth, frame.origin.y - BoxControlItemHalfWidth, frame.size.width + BoxControlItemWidth, frame.size.height + BoxControlItemWidth)];
    
    if (self) {
        // 创建背景图片 UIImageView,设置frame,添加
        self.contentView = [[UIImageView alloc] initWithFrame:CGRectMake(BoxControlItemHalfWidth, BoxControlItemHalfWidth, frame.size.width, frame.size.height)];
        self.contentImage = contentImage;
        [self addSubview:self.contentView];
        
        
        // 创建label 并且添加到contentView上
        UILabel *contentLabel = [[UILabel alloc]init];
        contentLabel.text = @"iOS开发,从入门到放弃!!";
        contentLabel.frame = contentLabelFrame;
        contentLabel.adjustsFontSizeToFitWidth = YES;
        contentLabel.numberOfLines = 0;
        contentLabel.font = [UIFont systemFontOfSize:100];
        contentLabel.minimumScaleFactor = 0.01;
        contentLabel.layer.masksToBounds = YES;
        [self.contentView addSubview:contentLabel];
        _contentLabel = contentLabel;
        
        
        // 箭头控制按钮,支持放大 缩小 旋转
        self.resizeControl = [self createResizeControl];
        [self addSubview:self.resizeControl];
        // 删除按钮,支持将当前的贴纸删除
        self.deleteControl = [self createDeleteControl];
        [self addSubview:self.deleteControl];
        // 图片左右翻转的控制按钮
        self.rightTopControl = [self createRightTopControl];
        [self addSubview:self.rightTopControl];
        
        // 左下角的复位按钮,主要作用是,点击以后,位置回到中心点
        self.leftBottomControl = [self createLeftBottomControl];
        [self addSubview:self.leftBottomControl];
        
        // 创建sharpLayer
        [self initShapeLayer];
        [self setupConfig];
        [self attachGestures];
        
    }
    return self;
}

- (UIImageView *)createResizeControl{
    UIImageView *resizeControl = [[UIImageView alloc] initWithFrame:CGRectMake(self.contentView.center.x + self.contentView.bounds.size.width / 2 - BoxControlItemHalfWidth, self.contentView.center.y + self.contentView.bounds.size.height / 2 - BoxControlItemHalfWidth, BoxControlItemWidth, BoxControlItemWidth)];
    resizeControl.backgroundColor=[UIColor whiteColor];
    resizeControl.layer.cornerRadius=BoxControlItemWidth/2.0;
    resizeControl.layer.masksToBounds=YES;
    resizeControl.image = [UIImage imageNamed:@"BoxStickerBundle.bundle/sticker_resize.png"];
    resizeControl.layer.borderWidth=1.0;
    resizeControl.layer.borderColor=StickerHexRGB(0x1296db).CGColor;
    return resizeControl;
}

- (UIImageView *)createDeleteControl{
    UIImageView *deleteControl = [[UIImageView alloc] initWithFrame:CGRectMake(self.contentView.center.x - self.contentView.bounds.size.width / 2 - BoxControlItemHalfWidth, self.contentView.center.y - self.contentView.bounds.size.height / 2 - BoxControlItemHalfWidth, BoxControlItemWidth, BoxControlItemWidth)];
    deleteControl.backgroundColor=[UIColor whiteColor];
    deleteControl.layer.cornerRadius=BoxControlItemWidth/2.0;
    deleteControl.layer.masksToBounds=YES;
    deleteControl.image = [UIImage imageNamed:@"BoxStickerBundle.bundle/sticker_delete.png"];
    deleteControl.layer.borderWidth=1.0;
    deleteControl.layer.borderColor=StickerHexRGB(0x1296db).CGColor;
    return deleteControl;
}
- (UIImageView *)createRightTopControl{
    UIImageView *rightTopControl = [[UIImageView alloc] initWithFrame:CGRectMake(self.contentView.center.x + self.contentView.bounds.size.width / 2 - BoxControlItemHalfWidth, self.contentView.center.y - self.contentView.bounds.size.height / 2 - BoxControlItemHalfWidth, BoxControlItemWidth, BoxControlItemWidth)];
    rightTopControl.backgroundColor=[UIColor whiteColor];
    rightTopControl.layer.cornerRadius=BoxControlItemWidth/2.0;
    rightTopControl.layer.masksToBounds=YES;
    rightTopControl.image = [UIImage imageNamed:@"BoxStickerBundle.bundle/sticker_flip.png"];
    rightTopControl.layer.borderWidth=1.0;
    rightTopControl.layer.borderColor=StickerHexRGB(0x1296db).CGColor;
    return rightTopControl;
}
- (UIImageView *)createLeftBottomControl{
    UIImageView *leftBottomControl = [[UIImageView alloc] initWithFrame:CGRectMake(self.contentView.center.x - self.contentView.bounds.size.width / 2 - BoxControlItemHalfWidth, self.contentView.center.y + self.contentView.bounds.size.height / 2 - BoxControlItemHalfWidth, BoxControlItemWidth, BoxControlItemWidth)];
    leftBottomControl.backgroundColor=[UIColor whiteColor];
    leftBottomControl.layer.cornerRadius=BoxControlItemWidth/2.0;
    leftBottomControl.layer.masksToBounds=YES;
    leftBottomControl.image = [UIImage imageNamed:@"BoxStickerBundle.bundle/sticker_resetCenter.png"];
    leftBottomControl.layer.borderWidth=1.0;
    leftBottomControl.layer.borderColor=StickerHexRGB(0x1296db).CGColor;
    return leftBottomControl;
}
// 选中以后的线条边框
- (void)initShapeLayer {
    _shapeLayer = [CAShapeLayer layer];
    // 大小等于图片的尺寸
    CGRect shapeRect = self.contentView.frame;
    [_shapeLayer setBounds:shapeRect];
    [_shapeLayer setPosition:CGPointMake(self.contentView.frame.size.width / 2, self.contentView.frame.size.height / 2)];
    [_shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
    [_shapeLayer setStrokeColor:[StickerHexRGB(0x1296db) CGColor]];
    [_shapeLayer setLineWidth:1.0f];
    [_shapeLayer setLineJoin:kCALineJoinRound];
    _shapeLayer.allowsEdgeAntialiasing = YES;
    [_shapeLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:5], [NSNumber numberWithInt:3], nil]];
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, shapeRect);
    [_shapeLayer setPath:path];
    CGPathRelease(path);
}

- (void)setupConfig {
    
    // 真正的拉伸系数
    _realScaleProduct = 1.0;
    // 假定的拉伸系数
//    _hypotheticalScaleProduct = (BoxMaxScale - 1.0) * 0.5 + BoxMaxScale;
    
    // 避免在一个界面上同时点击多个
    self.exclusiveTouch = YES;
    
    self.userInteractionEnabled = YES;
    self.contentView.userInteractionEnabled = YES;
    self.resizeControl.userInteractionEnabled = YES;
    self.deleteControl.userInteractionEnabled = YES;
    self.rightTopControl.userInteractionEnabled = YES;
    self.leftBottomControl.userInteractionEnabled = YES;
    
    
    self.enabledBorder = YES;
    self.selected = YES;
    
    self.enabledDeleteControl = YES;
    self.enabledResizeControl = YES;
    self.enabledRightTopControl = YES;
    self.enabledLeftBottomControl = YES;
}

- (void)attachGestures {
    
    // ContentView
    // ContentView UIImageView的手势添加 旋转手势,两个指头进行旋转
    UIRotationGestureRecognizer *rotateGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotate:)];
    [rotateGesture setDelegate:self];
    [self.contentView addGestureRecognizer:rotateGesture];
    
    // ContentView 捏合手势 用来放大缩小
    UIPinchGestureRecognizer *pinGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleScale:)];
    [pinGesture setDelegate:self];
    [self.contentView addGestureRecognizer:pinGesture];
    
    // ContentView 拖动手势,拖动位置
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleMove:)];
    [panGesture setMinimumNumberOfTouches:1];
    [panGesture setMaximumNumberOfTouches:2];
    [panGesture setDelegate:self];
    [self.contentView addGestureRecognizer:panGesture];
    
    // ContentView 点击手势, 回调handleTap:
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [tapRecognizer setNumberOfTapsRequired:1];
    [tapRecognizer setDelegate:self];
    [self.contentView addGestureRecognizer:tapRecognizer];
    
    // ResizeControl
    // ResizeControl的手势创建,支持放大和旋转
    BoxStickerRecognizer *singleHandGesture = [[BoxStickerRecognizer alloc] initWithTarget:self action:@selector(handleSingleHandAction:) anchorView:self.contentView];
    [self.resizeControl addGestureRecognizer:singleHandGesture];
    
    // DeleteControl
    // 删除控件,点击手势 回调handleTap:
    UITapGestureRecognizer *tapRecognizer2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [tapRecognizer2 setNumberOfTapsRequired:1];
    [tapRecognizer2 setDelegate:self];
    [self.deleteControl addGestureRecognizer:tapRecognizer2];
    
    // RightTopControl
    // 右上角的控件,图片位置交换,单击手势 回调handleTap:
    UITapGestureRecognizer *tapRecognizer3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [tapRecognizer3 setNumberOfTapsRequired:1];
    [tapRecognizer3 setDelegate:self];
    [self.rightTopControl addGestureRecognizer:tapRecognizer3];
    
    // LeftBottomControl
    // 复位功能,单击手势 回调handleTap:
    UITapGestureRecognizer *tapRecognizer4 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [tapRecognizer4 setNumberOfTapsRequired:1];
    [tapRecognizer4 setDelegate:self];
    [self.leftBottomControl addGestureRecognizer:tapRecognizer4];
}

#pragma mark - Handle Gestures

- (void)handleTap:(UITapGestureRecognizer *)gesture {
    // 如果点击了图片,那么把自己移动到父控件的顶端,并且通知外界代理,告诉自己被点击了
    if (gesture.view == self.contentView) {
        [self handleTapContentView];
        // 如果点击了删除控件
    } else if (gesture.view == self.deleteControl) {
        // 允许删除
        if (_enabledDeleteControl) {
            // 进行删除
            [self removeFromSuperview];
            // 通知外界代理
            if (_delegate && [_delegate respondsToSelector:@selector(stickerViewDidTapDeleteControl:)]) {
                [_delegate stickerViewDidTapDeleteControl:self];
            }
        }
        // 如果点了左右变化图片按钮,那么就变化图片
    } else if (gesture.view == self.rightTopControl) {
        UIImageOrientation targetOrientation = (self.contentImage.imageOrientation == UIImageOrientationUp ? UIImageOrientationUpMirrored : UIImageOrientationUp);
        UIImage *invertImage =[UIImage imageWithCGImage:self.contentImage.CGImage scale:1.0 orientation:targetOrientation];
        self.contentImage = invertImage;
        // 如果点击了复位按钮,那么将图片位置还原回去...
    } else if (gesture.view == self.leftBottomControl) {
        [UIView animateWithDuration:0.3 animations:^{
            self.center=self.superview.center;
        }];
    }
}

- (void)handleTapContentView {
    // 移动到顶部
    [self.superview bringSubviewToFront:self];
    // 通知外界代理
    if (_delegate && [_delegate respondsToSelector:@selector(stickerViewDidTapContentView:)]) {
        [_delegate stickerViewDidTapContentView:self];
    }
}

// 当拖动手势发生的时候,进行移动自己
- (void)handleMove:(UIPanGestureRecognizer *)gesture {
    CGPoint translation = [gesture translationInView:[self superview]];
    // Boundary detection
    CGPoint targetPoint = CGPointMake(self.center.x + translation.x, self.center.y + translation.y);
    targetPoint.x = MAX(0, targetPoint.x);
    targetPoint.y = MAX(0, targetPoint.y);
    targetPoint.x = MIN(self.superview.bounds.size.width, targetPoint.x);
    targetPoint.y = MIN(self.superview.bounds.size.height, targetPoint.y);
    
    [self setCenter:targetPoint];
    [gesture setTranslation:CGPointZero inView:[self superview]];
}

// 产生捏合手势的时候,进行调用这个方法,进行捏合
- (void)handleScale:(UIPinchGestureRecognizer *)gesture {
    CGFloat scale = gesture.scale;
    // Scale limit
    CGFloat currentScale = [[self.contentView.layer valueForKeyPath:@"transform.scale"] floatValue];
    if (scale * currentScale <= BoxMinScale) {
        scale = BoxMinScale / currentScale;
    } else if (scale * currentScale >= BoxMaxScale) {
        scale = BoxMaxScale / currentScale;
    }
    
    self.contentView.transform = CGAffineTransformScale(self.contentView.transform, scale, scale);

    

    gesture.scale = 1;
    
    // 调整四个点的位置...
    [self relocalControlView];
    
    _realScaleProduct *= scale;
    
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled || gesture.state == UIGestureRecognizerStateFailed) {
        if (_contentLabel == nil) {
            return;
        }
        CGFloat buMoHuScale =  _realScaleProduct * scale *[UIScreen mainScreen].scale;
        self.contentView.layer.contentsScale = buMoHuScale;
        [_contentLabel setContentScaleFactor:buMoHuScale];
    }
}

// 产生了旋转以后调用的方法
- (void)handleRotate:(UIRotationGestureRecognizer *)gesture {
    self.contentView.transform = CGAffineTransformRotate(self.contentView.transform, gesture.rotation);
    gesture.rotation = 0;
    
    [self relocalControlView];
}

// 放大 和 旋转的回调
- (void)handleSingleHandAction:(BoxStickerRecognizer *)gesture {
    CGFloat scale = gesture.scale;
    // Scale limit
    CGFloat currentScale = [[self.contentView.layer valueForKeyPath:@"transform.scale"] floatValue];
    if (scale * currentScale <= BoxMinScale) {
        scale = BoxMinScale / currentScale;
    } else if (scale * currentScale >= BoxMaxScale) {
        scale = BoxMaxScale / currentScale;
    }
    
    self.contentView.transform = CGAffineTransformScale(self.contentView.transform, scale, scale);
    self.contentView.transform = CGAffineTransformRotate(self.contentView.transform, gesture.rotation);
    

    
    [gesture reset];
    
    [self relocalControlView];
    
    _realScaleProduct *= scale;
    
    
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled || gesture.state == UIGestureRecognizerStateFailed) {
        if (_contentLabel == nil) {
            return;
        }
            CGFloat buMoHuScale =  _realScaleProduct * scale *[UIScreen mainScreen].scale;
            self.contentView.layer.contentsScale = buMoHuScale;
            [_contentLabel setContentScaleFactor:buMoHuScale];
    }
}

// 用来控制四个角的四个移动的点的位置,用在放大,和缩小以后的情况
- (void)relocalControlView {
    CGPoint originalCenter = CGPointApplyAffineTransform(self.contentView.center, CGAffineTransformInvert(self.contentView.transform));
    self.resizeControl.center = CGPointApplyAffineTransform(CGPointMake(originalCenter.x + self.contentView.bounds.size.width / 2.0f, originalCenter.y + self.contentView.bounds.size.height / 2.0f), self.contentView.transform);
    self.deleteControl.center = CGPointApplyAffineTransform(CGPointMake(originalCenter.x - self.contentView.bounds.size.width / 2.0f, originalCenter.y - self.contentView.bounds.size.height / 2.0f), self.contentView.transform);
    self.rightTopControl.center = CGPointApplyAffineTransform(CGPointMake(originalCenter.x + self.contentView.bounds.size.width / 2.0f, originalCenter.y - self.contentView.bounds.size.height / 2.0f), self.contentView.transform);
    self.leftBottomControl.center = CGPointApplyAffineTransform(CGPointMake(originalCenter.x - self.contentView.bounds.size.width / 2.0f, originalCenter.y + self.contentView.bounds.size.height / 2.0f), self.contentView.transform);
}

#pragma mark - UIGestureRecognizerDelegate
// 支持多个手势共同识别
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        return NO;
    } else {
        return YES;
    }
}

#pragma mark - Hit Test
// 点击事件的处理
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.hidden || !self.userInteractionEnabled || self.alpha < 0.01) {
        return nil;
    }
    if (_selected) {
        if (_enabledResizeControl && [self.resizeControl pointInside:[self convertPoint:point toView:self.resizeControl] withEvent:event]) {
            return self.resizeControl;
        }
        if (_enabledDeleteControl && [self.deleteControl pointInside:[self convertPoint:point toView:self.deleteControl] withEvent:event]) {
            return self.deleteControl;
        }
        if (_enabledRightTopControl && [self.rightTopControl pointInside:[self convertPoint:point toView:self.rightTopControl] withEvent:event]) {
            return self.rightTopControl;
        }
        if (_enabledLeftBottomControl && [self.leftBottomControl pointInside:[self convertPoint:point toView:self.leftBottomControl] withEvent:event]) {
            return self.leftBottomControl;
        }
    }
    if ([self.contentView pointInside:[self convertPoint:point toView:self.contentView] withEvent:event]) {
        return self.contentView;
    }
    // return nil for other area.
    return nil;
}

#pragma mark - Other
- (void)setSelected:(BOOL)selected {
    _selected = selected;
    self.deleteControl.hidden = _selected ? !_enabledDeleteControl : YES;
    self.resizeControl.hidden = _selected ? !_enabledResizeControl : YES;
    self.rightTopControl.hidden = _selected ? !_enabledRightTopControl : YES;
    self.leftBottomControl.hidden = _selected ? !_enabledLeftBottomControl : YES;
    BOOL hiddenBorder = _selected ? !_enabledBorder : YES;
    [self hiddenBorder:hiddenBorder];
}

- (void)hiddenBorder:(BOOL)hidden{
    if (hidden == YES) {
        [self.shapeLayer removeFromSuperlayer];
    }else{
        [self.contentView.layer addSublayer:self.shapeLayer];
    }
}



- (void)setContentImage:(UIImage *)contentImage {
    _contentImage = contentImage;
    self.contentView.image = _contentImage;
}


#pragma mark - 一些废弃的方法,不建议删除,建议注释掉
/*
 
    下面的这个方法是使用了SDWebImage来下载图片,支持了使用网络图片作为贴纸,但是这样的不好的地方在于,控件的本身的frame应该等于图片的尺寸,而图片恰恰是应该下载完成以后才能得知尺寸,所以,要使用这个方法,你必须先自己设置一个frame...然后才能下载图片,这样导致与frame和图片的尺寸是可能不一致的...
    使用起来并不方便....所以建议废弃
 
 */
// 方法需要的头文件
//#import "UIImageView+WebCache.h"

// 方法声明
//- (instancetype)initWithContentFrame:(CGRect)frame contentImageUrl:(NSString *)contentImageUrl;

// 方法实现
//- (instancetype)initWithContentFrame:(CGRect)frame contentImageUrl:(NSString *)contentImageUrl
//{
//    self = [super initWithFrame:CGRectMake(frame.origin.x - BoxControlItemHalfWidth, frame.origin.y - BoxControlItemHalfWidth, frame.size.width + BoxControlItemWidth, frame.size.height + BoxControlItemWidth)];
//    if (self) {
//        self.contentView = [[UIImageView alloc] initWithFrame:CGRectMake(BoxControlItemHalfWidth, BoxControlItemHalfWidth, frame.size.width, frame.size.height)];
//        [self.contentView sd_setImageWithURL:[NSURL URLWithString:contentImageUrl] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//            _contentImage=image;
//        }];
//        [self addSubview:self.contentView];
//        // 箭头控制按钮,支持放大 缩小 旋转
//        self.resizeControl = [self createResizeControl];
//        [self addSubview:self.resizeControl];
//        
//        // 删除按钮,支持将当前的贴纸删除
//        self.deleteControl = [self createDeleteControl];
//        [self addSubview:self.deleteControl];
//        
//        // 图片左右翻转的控制按钮
//        self.rightTopControl = [self createRightTopControl];
//        [self addSubview:self.rightTopControl];
//        
//        // 左下角的复位按钮,主要作用是,点击以后,位置回到中心点
//        self.leftBottomControl = [self createLeftBottomControl];
//        [self addSubview:self.leftBottomControl];
//        
//        // 初始化线条边框
//        [self initShapeLayer];
//        // 设置允许交互,设置一些默认的值
//        [self setupConfig];
//        // 手势添加
//        [self attachGestures];
//        
//    }
//    return self;
//}
@end
